/* Filename: jmp.c
 * Description:
 * Last modified: humble 20200320 19:52
 */
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

static jmp_buf save;

static void usage(void);

void d(void) {
    printf("%s begin\n", __FUNCTION__);
    longjmp(save, 6);
    printf("%s end\n", __FUNCTION__);
}

void c(void) {
    printf("%s begin\n", __FUNCTION__);
    printf("%s calling d()\n", __FUNCTION__);
    d();
    printf("%s d() return\n", __FUNCTION__);
    printf("%s end\n", __FUNCTION__);
}

void b(void) {
    printf("%s begin\n", __FUNCTION__);
    printf("%s calling c()\n", __FUNCTION__);
    c();
    printf("%s c() return\n", __FUNCTION__);
    printf("%s end\n", __FUNCTION__);
}

void a(void) {
    printf("%s begin\n", __FUNCTION__);
    int ret = setjmp(save);
    if(ret == 0){
        printf("%s calling b()\n", __FUNCTION__);
        b();
        printf("%s b() return\n", __FUNCTION__);
    }
    else{
        printf("%s Jumped to here,val:%u\n", __FUNCTION__, ret);
    }
    printf("%s end\n", __FUNCTION__);
}

int main(int argc, char **argv) {
    if(argc != 1){ fprintf(stderr, "argc !=1"); usage(); exit(1); }

    printf("%s begin\n", __FUNCTION__);
    printf("%s calling a()\n", __FUNCTION__);
    a();
    printf("%s a() return\n", __FUNCTION__);
    printf("%s end\n", __FUNCTION__);
    return 0;
}

static void usage(void) {
#define USAGE "Usage:\n\
  Helloworld\n"
    printf(USAGE);
}
